﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
using Microsoft.AspNetCore.Mvc;
using OwlLookNetCore.Models;
using OwlLookNetCore.Services;
using OwlLookNetCore.ViewModels;

namespace OwlLookNetCore.Controllers
{
    public class HomeController : Controller
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public HomeController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public IActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 小说查询返回页面
        /// </summary>
        /// <param name="wd"></param>
        /// <returns></returns>
        [HttpGet("Search")]
        public async Task<IActionResult> Search([FromQuery]string wd)
        {
            var ListSearch = new List<SearchViewModel>();

            //var httpHandle = new HttpClientHandler
            //{
            //    AllowAutoRedirect = true
            //};
            var http = _httpClientFactory.CreateClient("search");
            {
                //http.DefaultRequestHeaders.TryAddWithoutValidation("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36");
                //http.DefaultRequestHeaders.TryAddWithoutValidation("referer", "https://www.bing.com/");

                var search = $"intitle:{wd} 小说 阅读";
                var response = await http.GetStringAsync($"https://www.baidu.com/s?wd={search}&ie=utf-8&rn=15&vf_bl=1");

                var htmlParser = new HtmlParser();
                var html = await htmlParser.ParseDocumentAsync(response);
                var listElement = html.QuerySelectorAll(".result");
                foreach (var element in listElement)
                {
                    var a = element.QuerySelector("h3.t a") as IHtmlAnchorElement;
                    var realResponse = await http.GetAsync(a.Href);
                    var url = realResponse.Headers.Location.ToString();
                    var host = (new Uri(url)).Host;

                    if (RuleService.BlackDomain.Contains(host))
                    {
                        continue;
                    }

                    ListSearch.Add(new SearchViewModel
                    {
                        Title = a.Text,
                        Host = host,
                        Url = url.Replace("index.html", "").Replace("Index.html", ""),
                        IsRecommend = RuleService.RecommendDomain.Contains(host),
                        IsParse = RuleService.ParseDomain.ContainsKey(host),
                        Time = ""
                    });
                }
            }
            return View(ListSearch.OrderByDescending(r => r.IsRecommend).OrderByDescending(p => p.IsParse));
        }

        /// <summary>
        /// 显示小说章节列表
        /// </summary>
        /// <param name="url"></param>
        /// <param name="novels_name"></param>
        /// <returns></returns>
        [HttpGet("Chapter")]
        public async Task<IActionResult> Chapter([FromQuery]string url, [FromQuery]string novels_name)
        {
            var viewModel = new ChapterViewModel();

            var host = (new Uri(url)).Host;

            // 不能解析的网站直接跳转
            if (!RuleService.ParseDomain.ContainsKey(host))
            {
                return Redirect(url);
            }

            if (RuleService.ReplaceDomain.ContainsKey(host))
            {
                url = url.Replace(RuleService.ReplaceDomain[host].OldUrl, RuleService.ReplaceDomain[host].NewUrl);
            }

            viewModel.Url = url;
            viewModel.NovelsName = novels_name;

            var contents = new List<string>();
            var http = _httpClientFactory.CreateClient();
            {
                var responseAry = await http.GetByteArrayAsync(url);
                var response = RuleService.ParseDomain[host].Encoding == "GBK" ? Encoding.GetEncoding(RuleService.ParseDomain[host].Encoding).GetString(responseAry)
                    : Encoding.UTF8.GetString(responseAry);

                var htmlParser = new HtmlParser();
                var html = await htmlParser.ParseDocumentAsync(response);
                var chapters = html.QuerySelectorAll(RuleService.ParseDomain[host].ChapterSelector);

                viewModel.ParseUrlType = RuleService.ParseDomain[host].ParseUrlType;
                viewModel.Contents = chapters.Select(c =>
                    c.OuterHtml.Trim('[', ']', ',', ',', ' ', 'J', 'j', 's')
                        .Replace(", ", "").Replace("onerror", "").Replace("js", "")
                        .Replace("加入书架", ""));
            }

            return View(viewModel);
        }

        /// <summary>
        /// 显示小说内容
        /// </summary>
        /// <param name="url"></param>
        /// <param name="name"></param>
        /// <param name="chapter_url"></param>
        /// <param name="novels_name"></param>
        /// <returns></returns>
        [HttpGet("Content")]
        public async Task<IActionResult> Content([FromQuery]string url, [FromQuery]string name, [FromQuery]string chapter_url, [FromQuery]string novels_name)
        {
            var uri = new Uri(url);
            var host = uri.Host;

            var viewModel = new ContentViewModel
            {
                Url = url,
                ChapterUrl = chapter_url,
                NovelsName = novels_name,
                NextChapters = new Dictionary<string, string>(),
            };

            // 不能解析的网站直接跳转
            if (!RuleService.ParseDomain.ContainsKey(host))
            {
                return Redirect(url);
            }

            var http = _httpClientFactory.CreateClient();
            {
                var responseAry = await http.GetByteArrayAsync(url);
                var response = RuleService.ParseDomain[host].Encoding == "GBK" ? Encoding.GetEncoding(RuleService.ParseDomain[host].Encoding).GetString(responseAry)
                    : Encoding.UTF8.GetString(responseAry);

                var htmlParser = new HtmlParser();
                var html = await htmlParser.ParseDocumentAsync(response);
                var contents = html.QuerySelectorAll(RuleService.ParseDomain[host].ContentSelector);

                viewModel.ParseUrlType = RuleService.ParseDomain[host].ParseUrlType;

                // 解析小说标题
                viewModel.Name = Regex.Match(html.Title, @"(第?\s*[一二两三四五六七八九十○零百千万亿0-9１２３４５６７８９０]{1,6}\s*[章回卷节折篇幕集]\s*.*?)[_,-]")
                    .Groups[1].Value;

                viewModel.Contents = contents.Select(c =>
                    c.OuterHtml.Trim('[', ']', 'J', 'j', 's')
                    .Replace("http", "hs"));

                // 取得上下章节链接
                var strHtml = response.Replace("<<", "").Replace(">>", "");
                var nextReg = Regex.Matches(strHtml, @"(<a\s+.*?>.*[上前下后][一]?[页张个篇章节步].*?</a>)");
                var strNextReg = string.Join("\n", nextReg.Select(r => r.Value));
                var htmlLinks = await htmlParser.ParseDocumentAsync(strNextReg);
                var links = htmlLinks.QuerySelectorAll("a");
                foreach (IHtmlAnchorElement link in links)
                {
                    var title = link.TextContent.Replace(" ", "");
                    if (Regex.IsMatch(title, @"[上前下后][一]?[页张个篇章节步]"))
                    {
                        switch (viewModel.ParseUrlType)
                        {
                            case "0":
                                viewModel.NextChapters.TryAdd(title, link.Href.Replace(@"about://", $"{uri.Scheme}://{host}/"));
                                break;
                            default:
                                viewModel.NextChapters.TryAdd(title, link.Href.Replace(@"about://", $"{uri.Scheme}://{host}/"/*chapter_url*/));
                                break;
                        }

                    }
                }
            }

            return View(viewModel);
        }

        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
